/*
 * AES Crypto adapter class
 *
 * Rationale of converting String to Byte[].
 * You need to convert String -> Hex -> Byte[] and Byte[] -> Hex -> String.
 * Hex is the middle man.
 *
 * License: LGPL v3
 */
package org.passwordstore.util;

import org.passwordstore.Resource;

/**
 *
 * @author thotheolh
 */
public class AESCrypto {

    private Resource res;

    public AESCrypto(Resource res) {
        this.res = res;
    }

    public byte[] hashpwd(String password) {
        return getRes().getSql().hashPwd(password);
    }

    /**
     * Encrypt file method
     * @param content
     * @param passbytes
     * @return encrypted byte[]
     */
    public byte[] encryptFile(String content,byte[] passbytes) {
        try {//Does all the conversion from plain text to plain bytes before encryption to relieve user of need to do so

//            System.out.println("Hashed Password: " + ByteToHex(passbytes));//Diagnostics
            byte[] contentBytes = content.getBytes();
//            System.out.println("Plain text hex: " + ByteToHex(contentBytes));
            byte[] ciphertextBytes = getRes().getSql().encrypt(passbytes, contentBytes);
//            System.out.println("Cipher text: " + ByteToHex(ciphertextBytes));
            return ciphertextBytes;
        } catch (ArrayIndexOutOfBoundsException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * Decrypt file method
     * @param content
     * @param passbytes
     * @return byte[] decrypted plain byte array content
     */
    public byte[] decryptFile(byte[] content,byte[] passbytes) {
        try {
//            System.out.println("Hashed Password: " + ByteToHex(passbytes));//Diagnostics
//            System.out.println("Cipher text: " + ByteToHex(content));
            byte[] decryptedBytes = getRes().getSql().decrypt(passbytes, content);
//            System.out.println("Decrypted text: " + ByteToHex(decryptedBytes));
            return decryptedBytes;
        } catch (ArrayIndexOutOfBoundsException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     *Convert byte to string method
     * @param bytes
     * @return
     */
    public String ByteToString(byte[] bytes) {
        //byte[] to hex string
        String hexstr = ByteToHex(bytes);
        //hex string to plain string
        byte[] resbytes = new byte[hexstr.length() / 2];
        for (int i = 0; i < resbytes.length; i++) {
            resbytes[i] = (byte) Integer.parseInt(hexstr.substring(2 * i, 2 * i + 2), 16);
        }

        String resStr = new String(resbytes);
        return resStr;
    }

    /**
     * Convert string to byte method
     * @param string
     * @return byte[]
     */
    public byte[] StringToByte(String string) {
        //convert plain string to hex string
        char[] charArray = string.toCharArray();
        StringBuffer output = new StringBuffer();
        for (int i = 0; i < charArray.length; i++) {
            output.append(Integer.toHexString((int) charArray[i]));
        }
        //convert hex string to byte array
        return HexToByte(output.toString());
    }

    public String ByteToHex(byte[] byteArray) {
        String result = "";
        for (int i = 0; i < byteArray.length; i++) {
            result += Integer.toString((byteArray[i] & 0xff) + 0x100, 16).substring(1);
        }
        return result;
    }

    public byte[] HexToByte(String hexcode) {
        byte[] bytes = new byte[hexcode.length() / 2];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt(hexcode.substring(2 * i, 2 * i + 2), 16);
        }
        return bytes;
    }

    /**
     * @return the res
     */
    public Resource getRes() {
        return res;
    }

    /**
     * @param res the res to set
     */
    public void setRes(Resource res) {
        this.res = res;
    }
}
